//////////////////////////////////////////////
// main.cpp
//
//////////////////////////////////////////////

/// Includes ---------------------------------

// nkLog
#include <NilkinsLog/Loggers/ConsoleLogger.h>

// nkWinUi
#include <NilkinsWinUi/Components/Button.h>
#include <NilkinsWinUi/Components/ComponentManager.h>
#include <NilkinsWinUi/Components/Window.h>

#include <NilkinsWinUi/Inputs/InputSystem.h>

#include <NilkinsWinUi/Log/LogManager.h>

#include <NilkinsWinUi/System.h>

// Standards
#include <iostream>
#include <memory>

/// Function ---------------------------------

int main ()
{
	// Prepare logging capabilities
	std::unique_ptr<nkLog::Logger> logger = std::make_unique<nkLog::ConsoleLogger>() ;
	nkWinUi::LogManager::getInstance()->setReceiver(logger.get()) ;

	// Initialize the component
	// This will prepare averything and make the component ready to work on our system
	nkWinUi::System* uiSystem = nkWinUi::System::getInstance() ;

	if (!uiSystem->initialize())
		return -1 ;

	// Now we can allocate components and start making an interface
	// This goes through the component manager that will keep track of them for us
	nkWinUi::ComponentManager* componentManager = nkWinUi::ComponentManager::getInstance() ;

	// Components are the elements we can use to build a UI
	// Let's create the main window receiving our interface
	// It will be of type window, which is good to hold other components
	nkWinUi::Window* mainWindow = (nkWinUi::Window*)componentManager->createOrRetrieve("mainWindow", nkWinUi::COMPONENT_TYPE::WINDOW) ;

	// Components need to be setup and then loaded to make them use all their parameters and instantiate all they need from the system
	mainWindow->setWidth(800) ;
	mainWindow->setHeight(600) ;
	mainWindow->load() ;

	// Create a button we will be able to use to demonstrate a local callback
	// It will be inside the window we just created
	nkWinUi::Button* clickButton = (nkWinUi::Button*)componentManager->createOrRetrieve("clickButton", nkWinUi::COMPONENT_TYPE::BUTTON) ;

	clickButton->setLabel("Click me !") ;
	clickButton->setAreaInParent(nkMaths::Rectangle(350, 275, 100, 100)) ;

	clickButton->setParentComponent(mainWindow) ;
	clickButton->load() ;

	clickButton->setButtonClickCallback
	(
		[] (nkWinUi::Component* caller) -> void
		{
			std::cout << "Button clicked !" << std::endl ;
		}
	) ;

	// Flag to know when to stop the loop, kept here for callbacks
	bool windowOpened = true ;

	// Prepare the global closing callback
	nkWinUi::InputSystem::getInstance()->setCloseCallback
	(
		[&windowOpened] (nkWinUi::Component* caller) -> bool
		{
			windowOpened = false ;

			// We handled the event, return true to mean that the component itself can continue and proceed with its unloading
			return true ;
		}
	) ;

	// Now the system needs to be able to process its events
	// Usually this is done in the UI thread, in this tutorial this will be the main thread
	while (windowOpened)
		uiSystem->tick() ;

	// Once done we need to clean
	uiSystem->prepareForShutdown() ;
	uiSystem->kill() ;

	// Quick pause to see the console
	system("pause") ;

	return 0 ;
}